//
// Created by Eric on 2023/3/6.
//
#include "SimulationManager.h"
#include <iostream>
using namespace std;

// TODO 实现自动补全功能（玩一下罢了）

struct TrieTree {
    unordered_map<char, TrieTree*> children;
    int chars_vector_number;
    explicit TrieTree(const unordered_map<char, TrieTree*>& children, int chars_list_number = -1) : children(children), chars_vector_number(chars_list_number){}
    TrieTree() {
        chars_vector_number = -1;
    }
};

TrieTree* Insert(TrieTree* root, const string& str, int chars_list_number) {
    if (!root) {
        return nullptr;
    }
    if (str.size() == 1) {
        if(root->children[str[0]])
            root->children[str[0]]->chars_vector_number = chars_list_number;
        else
            root->children[str[0]] = new TrieTree(unordered_map<char, TrieTree*>(), chars_list_number);
        return root;
    }
    if (!root->children.count(str[0])) {
        root->children[str[0]] = new TrieTree(unordered_map<char, TrieTree*>(), -1);
    }
    root->children[str[0]] = Insert(root->children[str[0]], str.substr(1, str.size() - 1), chars_list_number);
    return root;
}

void LaunchSimulation(){
    SimulationManager simulation_manager(5,9,5);

    activate_point = false;

    string instruction;
    while(true){
        cout << ">> please enter instruction:"<<endl;
        getline(cin, instruction);
        if(instruction == "display aso"){
            for(auto& aso:simulation_manager.asobject_set_){
                aso.second.Display();
                cout << "==============" <<endl;
            }
        }
        else if(instruction == "debug"){
            activate_point = true;
        }
        else if(instruction == "quit_debug"){
            activate_point = false;
        }
        else if(instruction == "auto test"){
            cout << "=============================="<<endl;
            cout << ">> auto test start.";
            int count = 0;
            bool flag = true;
            int sub_instruction;
            while(flag){
                cout << ">> auto test round " << count << endl;
                simulation_manager.RaiseEvent();
                cout << "++++++New events:++++++"<<endl;
                for(auto e:simulation_manager.event_queue_) {
                    e.Display();
                    cout << "=================="<<endl;
                }
                simulation_manager.Execute();
                cout << "++++++Cur AO++++++"<<endl;
                for(auto& aso:simulation_manager.asobject_set_){
                    aso.second.Display();
                    cout << "==============" <<endl;
                }
                cout << "++++++Cur CIVI++++++"<<endl;
                for(auto& civi:simulation_manager.civilization_set_){
                    civi.second.Display();
                    cout << "==============" <<endl;
                }
                cout << "++++++Cur Relation++++++"<<endl;
                cout << setw(12*simulation_manager.dbi_.num_of_asobject+12)<< setfill('=')<<"=========================" << endl;
                cout<<setfill(' ');
                simulation_manager.relation_matrix_.Display();
                cout <<setw(12*simulation_manager.dbi_.num_of_asobject+12)<< setfill('=')<<"=========================" <<endl;
                cout << ">> continue?"<<endl;
                cin >> sub_instruction;
                flag = sub_instruction;
            }
        }
        else if(instruction == "help"){
            cout << "display baseinfo" <<endl;
            cout << "display civi" <<endl;
            cout << "display ao "<<endl;
            cout << "display relation"<<endl;
            cout << "display event" <<endl;
            cout << "raise event" <<endl;
            cout << "execute event"<<endl;
        }
        else if(instruction == "show civi"){
            for(auto& civi:simulation_manager.civilization_set_){
                civi.second.Display();
                cout << "==============" <<endl;
            }
        }
        else if(instruction == "show baseinfo"){
            cout << "number of civilization: " << simulation_manager.num_of_civilization_<<endl;
            cout << "number of asobject: " <<simulation_manager.num_of_asobject_<<endl;
            cout <<"universe size: " <<simulation_manager.universe_size_<<endl;
        }
        else if(instruction == "execute event"){
            simulation_manager.Execute();
            cout <<"done" <<endl;
        }
        else if(instruction == "raise event"){
            simulation_manager.RaiseEvent();
            cout<<"HERE ARE EVENTS:"<<endl;
            for(auto& event: simulation_manager.event_queue_){
                event.Display();
                cout << "=================="<<endl;
            }
            cout << "done"<<endl;

        }
        else if (instruction == "show relation"){
            cout << setw(12*simulation_manager.dbi_.num_of_asobject+12)<< setfill('=')<<"=========================" << endl;
            cout<<setfill(' ');
            simulation_manager.relation_matrix_.Display();
            cout <<setw(12*simulation_manager.dbi_.num_of_asobject+12)<< setfill('=')<<"=========================" <<endl;
        }
        else{
            cout <<">> wrong instruction!"<<endl;
        }
    }

    cout <<"hahahah" ;
    cout <<"hahahah";
}

int main(){
    LaunchSimulation();
}



